package br.unifor.cct.mia.util.missingvalue;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import br.unifor.cct.mia.dataenhancement.Database;
import br.unifor.cct.mia.dataenhancement.DatabaseUtil;
import br.unifor.cct.mia.dataenhancement.Structure;
import br.unifor.cct.mia.util.LoadFile;
import br.unifor.cct.mia.util.Methods;

public class MissingValueInputation {

	private static String[] datasets = {"breast","car","dermatology",	"diabetes","iris","zoo"};
	private static int pastas[] = {1,2,3};
	

	public static void main(String[] args) {
		try {
			
			for (String dbName: datasets) {
			
				for ( int p:pastas ) {
					
					String PATH = "./Convertidas/"+dbName+"/Estratificado/33/MV"+p+"/";
					String DATASET_DATA = PATH+dbName+"_data_train.txt";
					String DATASET_STRUC = PATH+dbName+"_struc.txt";
					
					MissingValueInputation mvi = new MissingValueInputation();
					mvi.insertMissingValues(DATASET_STRUC, DATASET_DATA, PATH, dbName);
					
				}
				
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	public void insertMissingValues(String strucOriginal,String dbOriginal,
			String PATH, String dbName) throws IOException {
		
		int porcentagens[] = {5,10,20};
		
		for ( int m:porcentagens ) {
			
			double porcentagem = 0;
			if ( m==5 ) porcentagem = 0.05;
			else if ( m==10 ) porcentagem = 0.10;
			else if ( m==20 ) porcentagem = 0.20;
			else if ( m==33 ) porcentagem = 0.33;
			else if ( m==50 ) porcentagem = 0.50;
			
			for ( int i=1; i<=5; i++ ) {
				String dbFinal = null;
				if ( m==5 )
					dbFinal = PATH+dbName+"_data_MV-0"+m+"_"+i+".txt";
				else
					dbFinal = PATH+dbName+"_data_MV-"+m+"_"+i+".txt";
				
				final Database db = LoadFile.loadDatabase(dbOriginal);	
				final DatabaseUtil dbUtil = new DatabaseUtil(db.getDbFile());		
				final Structure struc = LoadFile.loadStructure(strucOriginal);
				
				final File finalFile = new File(dbFinal);
				if ( !finalFile.exists() ) finalFile.createNewFile();
				final BufferedWriter writer = new BufferedWriter(new FileWriter(dbFinal));
				
				final int n = (int) ( (db.size()*struc.size())*porcentagem);
				

				System.out.println("DB SIZE: "+db.size()*struc.size());
				System.out.println("N: "+n);
				
				final ArrayList<Ponto> pontos = new ArrayList<Ponto>();
				while(pontos.size()<n) {
					int x = Methods.randIntValue(0, db.size()-1);
					int y = Methods.randIntValue(0, struc.size()-2);
					Ponto p = new Ponto(x,y);
					if ( !pontos.contains(p) ) {
						pontos.add(p);
					}
				}
				
				for(int x=0;x<db.size();x++) {
					String line = dbUtil.readLine(x);
					for(Ponto p:pontos) {
						if (p.x==x) {
							final int y=p.y;
							final String split[] = line.split(",");
							split[y] = "?";
							
							line = "";
							for(int j=0;j<split.length-1;j++ ) {
								line += split[j] + ",";
							}
							line += split[split.length-1];
						}
					}
					writer.write(line);
				}
				writer.flush();
				writer.close();
				
			}
		}		
		
		System.out.println("Done.");
	}
	
	public class Ponto {

		int x,y;
		
		public Ponto(int x, int y) {
			this.x=x;
			this.y=y;
		}
		

		@Override
		public int hashCode() {
			int hash = x*7 + y*13;
			return hash;
		}
		
		@Override
		public boolean equals(Object obj) {
			if ( !(obj instanceof Ponto) ) return false;
			Ponto p = (Ponto)obj;
			if ( p.x==x && p.y==y ) return true;			
			return false;
		}
	}

}
